package com.atguigu.controller;

import com.atguigu.entities.Constants;
import com.atguigu.entities.Content;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @Author: shenhao
 * @CreatTime: 2024/11/7 14:36
 * @Version: 1.0
 * 模拟观看直播间弹幕
 */
@RestController
@Slf4j
public class LiveController {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     *某个用户(userId=12)第一次进入房间,返回最新的前5条弹幕
     * http://localhost:24618/goRoom?roomId=100&userId=12
     */
    @GetMapping(value = "/goRoom")
    public List<Content> goRoom(Integer roomId, Integer userId) {
        List<Content> contents = new ArrayList<>();
        String key = Constants.ROOM_KEY+roomId;
        String userKey = Constants.ROOM_USER_KEY+userId;
        //进入房间,返回最新的前5条弹幕
        Set<ZSetOperations.TypedTuple<Content>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 4);
        //对应redis命令，ZREVRANGE room:100 0 4 WITHSCORES
        for (ZSetOperations.TypedTuple<Content> contentTypedTuple : set) {
            contents.add(contentTypedTuple.getValue());
            log.info("首次进房间取最新前5条弹幕content={},score={}", contentTypedTuple.getValue(), contentTypedTuple.getScore());
        }
        //把当前的时间T,保持到redis，供下次拉取用，看过的就不再推送
        long time = System.currentTimeMillis()/1000;
        redisTemplate.opsForValue().set(userKey,time);

        return contents;
    }

    /**
     *登录房间后持续观看，定时任务或者xxl-job 客户端间隔5秒钟来拉取数据
     * http://localhost:24618/commentList?roomId=100&userId=12
     */
    @GetMapping(value = "/commentList")
    public List<Content> commentList(Integer roomId, Integer userId) {
        List<Content> contents = new ArrayList<>();
        String key = Constants.ROOM_KEY+roomId;
        String userKey = Constants.ROOM_USER_KEY+userId;
        long now = System.currentTimeMillis()/1000;
        //拿取上次的读取时间
        long ago=0L;
        Object object = redisTemplate.opsForValue().get(userKey);
        if (object != null) {
            ago = Long.parseLong(object.toString());
        }else {
            ago = now;
        }
        //获取上次到现在的数据 ZREVRANGE room:100 0 4 WITHSCORES
        // rangeByScoreWithScores    方法要写对
        // 通过分数查询 从 Sorted Set 中获取 score 介于 min max 和 from sorted set 的 s 的集合Tuple。
        Set<ZSetOperations.TypedTuple<Content>> set = redisTemplate.opsForZSet().rangeByScoreWithScores(key, ago, now);
        for (ZSetOperations.TypedTuple<Content> contentTypedTuple : set) {
            contents.add(contentTypedTuple.getValue());
            log.info("持续观看直播content={},score={}", contentTypedTuple.getValue(), contentTypedTuple.getScore());
        }
        //把当前的时间Time,保持到redis，供下次拉取用
        now = System.currentTimeMillis()/1000;
        this.redisTemplate.opsForValue().set(userKey,now);
        return contents;
    }
}
